package subject;

import db.DatabaseConnection;
import subject.Observer;
import subject.Subject;
import trans.Transaction;
import trans.TransactionFactory;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class AccountManager implements Subject {
    private List<Observer> observers;
    private List<Transaction> transactions;

    public AccountManager() {
        observers = new ArrayList<>();
        transactions = new ArrayList<>();
    }

    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(transactions);
        }
    }

    public void addTransaction(Transaction transaction) {
        transaction.execute(); // 执行记账
        transactions.add(transaction); // 添加到记账列表
        notifyObservers(); // 通知所有观察者
    }

    public void deleteTransaction(int id) {
        transactions.removeIf(t -> t.getId() == id);
        deleteTransactionFromDatabase(id);
        notifyObservers(); // 通知所有观察者
    }

    public Transaction getTransactionById(int id) {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            conn = DatabaseConnection.getInstance().getConnection();
            stmt = conn.prepareStatement("SELECT * FROM transactions WHERE id = ?");
            stmt.setInt(1, id);
            rs = stmt.executeQuery();
            if (rs.next()) {
                int transactionId = rs.getInt("id");
                String description = rs.getString("description");
                double amount = rs.getDouble("amount");
                String type = rs.getString("type");
                Transaction transaction = TransactionFactory.getTransaction(type, description, amount,transactionId);
                return transaction;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                // 不要关闭 conn，因为它是由单例管理的
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    public void updateTransaction(Transaction transaction) {
        for (int i = 0; i < transactions.size(); i++) {
            if (transactions.get(i).getId() == transaction.getId()) {
                transactions.set(i, transaction);
                transaction.execute(); // 更新记账记录
                notifyObservers(); // 通知所有观察者
                return;
            }
        }
    }

    public List<Transaction> getTransactions() {
        return transactions;
    }

    public List<Transaction> getAllTransactionsFromDatabase() {
        List<Transaction> allTransactions = new ArrayList<>();
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            conn = DatabaseConnection.getInstance().getConnection();
            stmt = conn.prepareStatement("SELECT * FROM transactions");
            rs = stmt.executeQuery();
            while (rs.next()) {
                int id = rs.getInt("id");
                String description = rs.getString("description");
                double amount = rs.getDouble("amount");
                String type = rs.getString("type");
                Transaction transaction = TransactionFactory.getTransaction(type, description, amount,id);
                allTransactions.add(transaction);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                // 不要关闭 conn，因为它是由单例管理的
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return allTransactions;
    }

    private void deleteTransactionFromDatabase(int id) {
        Connection conn = null;
        PreparedStatement stmt = null;

        try {
            conn = DatabaseConnection.getInstance().getConnection();
            stmt = conn.prepareStatement("DELETE FROM transactions WHERE id = ?");
            stmt.setInt(1, id);
            stmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (stmt != null) stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

}